/**
 * This file is released under the GNU General Public License.
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 2008-2009 WURFL-Pro srl
 */
/* $Id: StringUtils.java 1045 2009-03-09 15:52:53Z filippo.deluca $ 
 * This file is released under the GNU General Public License. 
 * Refer to the COPYING file distributed with this package.
 *
 * Copyright (c) 2008-2009 WURFL-Pro S.r.l.
 */
package net.sourceforge.wurfl.core.utils;

import java.util.List;
import java.util.SortedSet;

import net.sourceforge.wurfl.core.handlers.matchers.strategy.LDMatcher;
import net.sourceforge.wurfl.core.handlers.matchers.strategy.RISMatcher;

import org.apache.commons.lang.text.StrBuilder;

/**
 * Strings matching utility class.
 * 
 * <p>
 * This class contains the utility methods for the strings.
 * </p>
 * 
 * @author WURFL-PRO SRL, Rome, Italy
 * @version $Id: StringUtils.java 1045 2009-03-09 15:52:53Z filippo.deluca $
 */
public final class StringUtils {

	/**
	 * Return the position of first slash of the userAgent string.
	 * 
	 * @param target
	 *            A string to search first slash
	 * @return A index of first slash in the string or, if the string does not
	 *         contain a slash, the string length
	 */
	public static int firstSlash(String target) {

		return indexOfOrLength(target, "/");
	}

	/**
	 * Return the index of second of the given string.
	 * 
	 * @param target
	 *            A string on which find second slash.
	 * @return A index of second slash in the string.
	 */
	public static int secondSlash(String target) {

		return ordinalIndexOfOrLength(target, "/", 2);

	}

	/**
	 * Return the position of first space of the given string.
	 * 
	 * @param target
	 *            A string to search first slash
	 * @return A index of first space in the string or, if the string not
	 *         containing a space, the whole string length
	 */
	public static int firstSpace(String target) {
		
		return indexOfOrLength(target, " ");
	}
	
	public static int indexOfOrLength(String target, String needle) {

		return indexOfOrLength(target, needle, 0);
	}
	
	public static int indexOfOrLength(String target, String needle, int startIndex) {
			
		return ordinalIndexOfOrLength(target, needle, 1, startIndex);
	}
	
	public static int ordinalIndexOfOrLength(String target, String needle, int ordinal) {
		
		return ordinalIndexOfOrLength(target, needle, ordinal, 0);
	}
	
	public static int ordinalIndexOfOrLength(String target, String needle, int ordinal, int startIndex) {
		
		String workingTarget = target.substring(startIndex + 1);
		
		int position = org.apache.commons.lang.StringUtils.ordinalIndexOf(workingTarget, needle, ordinal);
		position =  position > -1 ? position : workingTarget.length();
		
		position = position + startIndex + 1;
		
		return position > -1 ? position : target.length();
	}
	
	
	/**
	 * This method use the {@link RISMatcher} to search the given needle.
	 * 
	 * @param needle
	 *            String to search
	 * @param candidates
	 *            Strings to search against
	 * @param tollerance
	 *            The tolerance to use in matching.
	 * 
	 * @see RISMatcher#match(SortedSet, String, int)
	 */
	public static String risMatch(SortedSet candidates, String needle,
			int tolerance) {

		return RISMatcher.INSTANCE.match(candidates, needle, tolerance);
	}

	/**
	 * This method use the {@link LDMatcher} to search the given needle.
	 * 
	 * @param needle
	 *            String to search
	 * @param candidates
	 *            Strings to search against
	 * @param tollerance
	 *            The tolerance to use in matching.
	 * 
	 * @see LDMatcher#match(SortedSet, String, int)
	 */
	public static String ldMatch(SortedSet candidates, String needle,
			int tolerance) {
		return LDMatcher.INSTANCE.match(candidates, needle, tolerance);
	}

	/**
	 * Display a device hierarchy as String: generic -> ... -> root.
	 * 
	 * @param hierarchy
	 *            The hierarchy to convert.
	 * @return A string representing the given hierarchy.
	 */
	public static String hierarchyAsString(List/* ModelDevice */hierarchy) {

		StrBuilder hierarchyBuilder = new StrBuilder();

		for (java.util.Iterator hIt = hierarchy.iterator(); hIt.hasNext();) {
			hierarchyBuilder.append(hIt.next());
			if (hIt.hasNext()) {
				hierarchyBuilder.append(" -> ");
			}
		}

		return hierarchyBuilder.toString();
	}

}
